// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: tu@tulrich.com (Thatcher Ulrich)

// C++ translation of the WebGL benchmark code written in Javascript.
// Uses the Desktop OpenGL API.

#ifndef WEBGL_BENCH_H__
#define WEBGL_BENCH_H__

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <vector>

using std::vector;

void CheckGlError(const char* msg);

struct RenderInfo {
  RenderInfo() : vshader(0), fshader(0), program(0),
                 position_location(0), t0_uv_location(0),
                 tri_count(0), draw_count(0) {
    memset(projection_matrix, 0, sizeof(projection_matrix));
    memset(camera_orient, 0, sizeof(camera_orient));
    memset(mvp, 0, sizeof(mvp));
  }

  int vshader;
  int fshader;
  int program;
  int position_location;
  int t0_uv_location;
  int mvp_location;
  float projection_matrix[16];
  float camera_orient[16];
  float mvp[16];

  long long tri_count;
  long long draw_count;
};

enum PrimType {
  BENCH_TRIANGLES,
  BENCH_TRIANGLE_STRIP
};

class Model {
 public:
  Model();
  ~Model();

  void Init(enum PrimType prim_type, int x, int y, int d, int grid_dim);

  void Draw(RenderInfo* ri) const;

  const float* matrix() const {
    return matrix_;
  }

 private:
  void MakeGridTriangles(int dim, vector<GLshort>* out);
  void MakeGridTriangleStrip(int dim, vector<GLshort>* out);

  float matrix_[16];
  int texture_;
  GLuint vertices_;
  GLuint indices_;
  int index_count_;
  int index_type_;
  int triangle_count_;
};

class Bench {
 public:
  Bench();
  ~Bench();

  void Init(int depth_x, int dim, enum PrimType prim_type);

  void Draw(RenderInfo* ri) const;

 private:
  vector<Model*> models_;
};

#endif  // WEBGL_BENCH_H__
